﻿@using AcBlog.UI.Components.Loading
@inject ILogger<Loader> Logger
@inject NotificationService NotificationService

@if (UseSkeleton)
{
    <Skeleton Loading="State is DataLoadingState.Loading" Active>
        @switch (State)
        {
            case DataLoadingState.Success:
                @ChildContent
                break;
            case DataLoadingState.Failed:
                <Alert Message="Loading Failed" Type="@AlertType.Error" OnClose="@Load" CloseText="Reload" ShowIcon Closable />
                break;
        }
    </Skeleton>
}
else
{
    @switch (State)
    {
        case DataLoadingState.Loading:
            @if (UseSpin)
            {
                <Spin Size="small" />
            }
            else
            {
                <Loading></Loading>
            }
            break;
        case DataLoadingState.Success:
            @ChildContent
            break;
        case DataLoadingState.Failed:
            @if (FailingContent is null)
            {
                <Alert Message="Loading Failed" Type="@AlertType.Error" OnClose="@Load" CloseText="Reload" ShowIcon Closable />
            }
            else
            {
                @FailingContent
            }
            break;
    }
}


@code {
    [Parameter]
    public bool UseSkeleton { get; set; } = false;

    [Parameter]
    public bool UseSpin { get; set; } = false;

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public RenderFragment FailingContent { get; set; }

    [Parameter]
    public string LoadKey { get; set; } = string.Empty;

    [Parameter]
    public EventCallback OnLoad { get; set; }

    [Parameter]
    public EventCallback OnLoaded { get; set; }

    [Parameter]
    public bool AutoLoad { get; set; } = true;

    private string LastLoadKey { get; set; } = null;

    public DataLoadingState State { get; set; } = DataLoadingState.Initialized;

    private bool NeedCallback { get; set; } = false;

    protected override async Task OnParametersSetAsync()
    {
        if (AutoLoad && LastLoadKey != LoadKey && State != DataLoadingState.Loading)
        {
            await Load();
        }
        await base.OnParametersSetAsync();
    }

    public async Task Load()
    {
        State = DataLoadingState.Loading;
        try
        {
            await OnLoad.InvokeAsync(null);
            State = DataLoadingState.Success;
            NeedCallback = true;
        }
        catch (Exception ex)
        {
            Logger.Log(LogLevel.Error, ex, "Loading failed");
            State = DataLoadingState.Failed;
        }
        LastLoadKey = LoadKey;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (NeedCallback && State is DataLoadingState.Success)
        {
            NeedCallback = false;
            await OnLoaded.InvokeAsync(null);
        }
        await base.OnAfterRenderAsync(firstRender);
    }
}
